package laboratorioV.grupo21.tp4.deposito;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.LinkedHashMap;

import laboratorioV.grupo21.tp4.clientes.Cliente;
import laboratorioV.grupo21.tp4.productos.Producto;

public class Compartimiento implements Serializable {
	/**
	 * Almacena el stock de un tipo de producto.
	 * puede almacenar stock de varios clietnes 
	 */
	private static final long serialVersionUID = -1725474929690887070L;
	private Producto producto;
	private Integer cantidadEspaciosMax;
	private LinkedHashMap<Cliente, Integer> stock; //stock perteneciente a cada cliente key: Cliente value:stock del cliente
	
	public Boolean contains(Cliente client){
		for (Cliente cli : stock.keySet()) {
			if(cli.equals(client))
				return true;
		}
		return false;		
	}

	public Compartimiento(Producto pProducto, Integer pCantidadMaxima) {
		stock = new LinkedHashMap<Cliente,Integer>();
		producto = pProducto;
		cantidadEspaciosMax = pCantidadMaxima;		
	}
		
	public Integer getCantidadMaxima() {
		return cantidadEspaciosMax;
	}

	public Producto getProducto() {
		return producto;
	}
	
	
	public Integer getStockActual(){
		//
		Integer stockTotal = 0;
		for(Integer stockCliente: stock.values()){
			stockTotal+=stockCliente;
		}
		return stockTotal;
	}
	
	public Integer getEspaciosDisponibles(){
		Integer espaciosDisponibles = 0;
		espaciosDisponibles = (getCantidadMaxima() - getStockActual());
		return espaciosDisponibles;
	}

	public Integer addStock(Cliente pClient, Integer pCantidad){
		/*
		 * Retorna la cantidad de productos que FALTO agregar
		 * -Si quedan 5 lugares disponibles, y se quiere cargar 8,
		 * el metodo va a retornar 3
		 */
		
		Integer cantidadACargar = 0;
		Integer espacioDisponible = getEspaciosDisponibles();
		Integer stockCliente = stock.get(pClient);
		
		
		if(pCantidad>espacioDisponible)			
			cantidadACargar = espacioDisponible;
		else
			cantidadACargar = pCantidad;
		
		Integer cantidadNoGuardada = pCantidad - cantidadACargar; //valor a retornar
		
		if (stockCliente == null)
			stockCliente = 0;
					
		stock.put(pClient, (stockCliente+cantidadACargar));
		
		return cantidadNoGuardada; 
		
	}
	public synchronized Integer saveStock(Integer pIdPasillo, String pLado, Integer pFila, Integer pColumna, Cliente pClient, Integer pCantidad, Boolean update){
		/*
		 * Retorna la cantidad de productos que FALTO agregar
		 * -Si quedan 5 lugares disponibles, y se quiere cargar 8,
		 * el metodo va a retornar 3
		 */
		
		Integer cantidadACargar = 0;
		Integer espacioDisponible = getEspaciosDisponibles();
		Integer stockCliente = stock.get(pClient);
		
		
		if(pCantidad>espacioDisponible)			
			cantidadACargar = espacioDisponible;
		else
			cantidadACargar = pCantidad;
		
		Integer cantidadNoGuardada = pCantidad - cantidadACargar; //valor a retornar
		
		if (stockCliente == null)
			stockCliente = 0;
					
		//stock.put(pClient, (stockCliente+cantidadACargar));
		//Guarda en la BD
		PreparedStatement ps = null;		
		Connection con = null;
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
			
			con = DriverManager.getConnection("jdbc:derby:derbyDb/TP6;create=true");			
			if(update){
				ps = con.prepareStatement("UPDATE STOCK SET STOCK=?  WHERE DEPOSITO = ? AND ID_PASILLO = ? AND LADO = ? AND FILA = ? AND COLUMNA = ? AND ID_CLIENTE = ? ");
				ps.setInt(1, stockCliente+cantidadACargar);
				ps.setString(2, "Mercaderia de Multiproposito");
				ps.setInt(3, pIdPasillo);
				ps.setString(4, pLado);
				ps.setInt(5, pFila);
				ps.setInt(6, pColumna);
				ps.setString(7,pClient.getId());
				if(ps.executeUpdate() ==0){
					ps = con.prepareStatement("INSERT INTO STOCK (DEPOSITO, ID_PASILLO, LADO, FILA, COLUMNA, ID_CLIENTE, STOCK, ID_PRODUCTO) VALUES(?,?,?,?,?,?,?,?) ");
					
					ps.setString(1, "Mercaderia de Multiproposito");
					ps.setInt(2, pIdPasillo);
					ps.setString(3, pLado);
					ps.setInt(4, pFila);
					ps.setInt(5, pColumna);
					ps.setString(6, pClient.getId());
					ps.setInt(7, stockCliente+cantidadACargar);
					ps.setInt(8, this.getProducto().getId());
					ps.executeUpdate();
				}
				
			}
			else{
				ps = con.prepareStatement("INSERT INTO STOCK (DEPOSITO, ID_PASILLO, LADO, FILA, COLUMNA, ID_CLIENTE, STOCK, ID_PRODUCTO) VALUES(?,?,?,?,?,?,?,?) ");
				
				ps.setString(1, "Mercaderia de Multiproposito");
				ps.setInt(2, pIdPasillo);
				ps.setString(3, pLado);
				ps.setInt(4, pFila);
				ps.setInt(5, pColumna);
				ps.setString(6, pClient.getId());
				ps.setInt(7, stockCliente+cantidadACargar);
				ps.setInt(8, this.getProducto().getId());
				ps.executeUpdate();
			}
				
			
		}
		catch (Exception e) {
			System.out.print("Error al guardar stock");
		}
		finally{
			try {
				if(ps != null)ps.close();				
				if(con != null)con.close();
				return cantidadNoGuardada;
			} catch (Exception e) {
				System.out.print("Error al guardar stock");
			}
		}
		
		return cantidadNoGuardada;
		
	}
	
	public Integer getStockCliente(Cliente client){
		Integer stockCliente = 0;	
		for (Cliente cli: stock.keySet()) {
			if(cli.equals(client))
				stockCliente = stock.get(cli);
		}
		return stockCliente;
	}
	
	

	
}
